package com.xx.sg.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xx.sg.own.entity.ForestSpot;
import com.xx.sg.own.entity.Point;
import com.xx.sg.own.service.ForestSpotService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


@RestController
@RequestMapping("/forestSpot")
@Tag(name = "林斑数据", description = "林斑数据API")
public class ForestSpotController {

    @Autowired
    private ForestSpotService forestSpotService;


    // POLYGON((123.54371 49.22707, 123.67417 49.22707, 123.54371 49.14336, 123.67417 49.14336, 123.54371 49.22707))
    @GetMapping("/checkIntersect")
    @Operation(summary = "返回有相交数据集", description = "返回有相交数据集")
    public List<ForestSpot> checkIntersect(String wkt) {
        return forestSpotService.checkIntersect(wkt);
    }

    @PostMapping("/checkBoundaryIntersect")
    @Operation(summary = "返回边界相交数据集", description = "返回边界相交数据集")
    public List<ForestSpot> checkBoundaryIntersect(@RequestBody List<Point> points) {

        List<ForestSpot> list = new ArrayList<>();
        for (int i = 0; i < points.size() - 1; i++) {
            LambdaQueryWrapper<ForestSpot> wrapper = new LambdaQueryWrapper<>();
            String wkt = String.format("LINESTRING(%s %s, %s %s)", points.get(i).getLongitude(), points.get(i).getLatitude(), points.get(i + 1).getLongitude(), points.get(i + 1).getLatitude());
            System.err.println("wkt = " + wkt);
            list.addAll(forestSpotService.checkIntersect(wkt));
        }
        return list;
    }

    @GetMapping("/load")
    @Operation(summary = "写入数据", description = "写入数据")
    public void loadForestSpot(String filePath, String regionId) {
        File file = new File(filePath);
        try {
            //  创建 JsonFactory 和 JsonParser（流式解析）
            JsonFactory factory = new JsonFactory();
            JsonParser parser = factory.createParser(file);

            // 创建 ObjectMapper（用于映射 Java Bean）
            ObjectMapper objectMapper = new ObjectMapper();

            // 定位到 "features" 数组
            while (!parser.isClosed()) {
                JsonToken token = parser.nextToken();

                if (JsonToken.FIELD_NAME.equals(token) && "features".equals(parser.getCurrentName())) {
                    parser.nextToken(); // 进入数组

                    // 遍历 "features" 数组，每次读取一个 Feature 对象
                    while (parser.nextToken() != JsonToken.END_ARRAY) {
                        JsonNode featureNode = objectMapper.readTree(parser);  // 读取每个 feature 为 JsonNode

                        featureNode.fields().forEachRemaining(entry -> {
                            if ("null".equals(entry.getValue().asText().trim())) {
                                System.err.println(entry.getValue().asText());
                                ((ObjectNode) featureNode).put(entry.getKey(), (String) null);  // 将 "null" 字符串转换为 null
                            }
                        });

                        JsonNode propertiesNode = featureNode.get("properties");
                        ForestSpot forestSpot = objectMapper.treeToValue(propertiesNode, ForestSpot.class);
                        forestSpot.setId(String.valueOf(featureNode.get("id")));
                        forestSpot.setType(String.valueOf(featureNode.get("type")));
                        forestSpot.setRegionId(regionId);

                        StringBuilder sb = new StringBuilder();
                        String formatStr = "\"%s\",";
                        if (propertiesNode != null && propertiesNode.isObject()) {
                            Iterator<String> fieldNames = propertiesNode.fieldNames();
                            while (fieldNames.hasNext()) {
                                String fieldName = fieldNames.next();
                                sb.append(String.format(formatStr, fieldName, fieldName));
                            }
                        } else {
                            System.out.println("No properties found");
                        }
                        System.err.println(sb.toString());
                        forestSpotService.save(forestSpot);
                        String wkt = formatGeometryWKT(featureNode.get("geometry"));

                        forestSpotService.updateGeometry(forestSpot.getId(), wkt);
                    }
                }
            }

            parser.close(); // 关闭解析器，释放资源

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String formatGeometryWKT(JsonNode geometryNode) {

        String type = geometryNode.get("type").asText();
        // 获取坐标数组

        StringBuilder wkt = new StringBuilder();
        if ("Polygon".equals(type)) {
            wkt.append("POLYGON((");
            JsonNode coordinatesNode = geometryNode.get("coordinates").get(0);
            if (coordinatesNode.isArray()) {
                for (int i = 0; i < coordinatesNode.size(); i++) {
                    JsonNode coordinateNode = coordinatesNode.get(i);
                    wkt.append(coordinateNode.get(0).asText()).append(" ").append(coordinateNode.get(1).asText());
                    if (i < coordinatesNode.size() - 1) {
                        wkt.append(", ");
                    }
                }
            }
            wkt.append("))");
        } else if ("MultiPolygon".equals(type)) {
            wkt.append("MULTIPOLYGON(");
            JsonNode coordinatesNode = geometryNode.get("coordinates");
            for (int i = 0; i < coordinatesNode.size(); i++) {
                JsonNode coordinateNode = coordinatesNode.get(i).get(0);
                wkt.append("((");
                for (int j = 0; j < coordinateNode.size(); j++) {
                    JsonNode pointNode = coordinateNode.get(j);
                    wkt.append(pointNode.get(0).asText()).append(" ").append(pointNode.get(1).asText());
                    if (j < coordinateNode.size() - 1) {
                        wkt.append(", ");
                    }
                }
                if (i < coordinatesNode.size() - 1) {
                    wkt.append(")), ");
                } else {
                    wkt.append("))");
                }
            }
            wkt.append(")");
        }
        return wkt.toString();
    }
}


